﻿/* 
 *  <copyright file="TriggerCmp.cs" company="Wesley Jowitt">
 *  
 *  SobrietyEngine: Copyright (c) 2011 Wesley Jowitt
 *  
 *  This software is distributed under a software license.
 *   * As of the creation time of this file, the license in use is the Microsoft Permissive License (Ms-PL) 
 *    * The license can be viewed at:
 *     * License.Txt in the root folder of this project
 *      * http://sobrietyengine.codeplex.com/license
 *       * http://www.microsoft.com/opensource/licenses.mspx
 *       
 *  </copyright>
 *   */

using System;
using System.Collections.Generic;

using SobrietyEngine.Common;
using SobrietyEngine.Actor;
using SobrietyEngine.Components;
using SobrietyEngine.Components.Physics;
using SobrietyEngine.Components.Physics.OnCollision;
using SobrietyEngine.Logging;
using SobrietyEngine.Guids;
using SobrietyEngine.Events.Component;

namespace SobrietyEngine.Components.Trigger
{
    public class TriggerCmp: BaseComponent, ITrigger
    {
        //pressure switch is 'on' when colliding with, off when not
        public Boolean IsPressureSwitch { get; set; }
        public List<IActor> ActorsOnTrigger { get; protected set; }

        public Boolean TriggerLimit { get; set; }
        public int TriggersLeft { get; set; }

        public Boolean TriggerValue { get; private set; }
        //can we trigger multiple times at once
        public Boolean MultiTrigger { get; set; }

        public String TriggerName { get; set; }

        //todo: maybe trigger on specific actor only? 
        //todo: trigger on player only?
         public TriggerCmp()
            : base()
        {
            ActorsOnTrigger = new List<IActor>();
            TriggerName = "Unassigned";
        }

        public TriggerCmp(String triggerName, bool isPressureSwitch, bool triggerLimit, int triggersLeft, bool multiTrigger)
            : this()
        {
            TriggerName = triggerName;
            IsPressureSwitch = isPressureSwitch;
            TriggerLimit = triggerLimit;
            TriggersLeft = triggersLeft;
            MultiTrigger = multiTrigger;
        }

        public void ToggleTrigger(CGuid byWho)
        {
            TriggerValue = !TriggerValue;
            Trigger(TriggerValue, byWho);
        }

        public override Type[] SupportedInterfaces()
        {
            return new Type[] { typeof(ITrigger) };
        }

        public void Trigger(Boolean triggerState, CGuid byWho)
        {            

            //if we are already triggerd and we are not set to multi trigger
            if (TriggerValue == true && triggerState == true && MultiTrigger == false)
                return;

            //set our value
            TriggerValue = triggerState;

            //if we have a trigger limit
            if (TriggerLimit == true)
            {
                if (TriggersLeft > 0)
                {
                    TriggersLeft--;
                    Actor.EventRouter.RaiseEvent(this, new Triggered(this, byWho));
                }
            }
            else
                Actor.EventRouter.RaiseEvent(this, new Triggered(this, byWho));

        }

        public void ForceTrigger(CGuid byWho)
        {
            Actor.EventRouter.RaiseEvent(this, new Triggered(this, byWho));
        }
    }
}
